_Pragma("once")

#include <type_traits>

namespace sdl_engine {

template <typename T,
          template <typename U, typename = std::allocator<U>> typename Cont = std::vector>
class Stock {
public:
    Stock() = default;
    Stock(const Stock&) = delete;
    Stock& operator=(const Stock&) = delete;
    ~Stock() { Clear(); }

    template <typename ... Args>
    std::conditional_t<std::is_pointer_v<T>, T, T*> Create(Args ... args) {
        if constexpr (std::is_pointer_v<T>) {
            Add(new std::remove_pointer_t<T>(args ...));
            return container_.back();
        } else {
            container_.emplace_back(args ...);
            return &container_.back();
        }
    }

    void Add(const T& elem) {
        container_.push_back(elem);
    }

    int GetSize() const { return container_.size(); }

    void Clear() {
        if constexpr (std::is_pointer_v<T>) {
            std::for_each(container_.begin(), container_.end(),
                          [](T& elem){ delete elem; });
        }
        container_.clear();
    }

    Cont<T>& GetContainer() { return container_; }

private:
    Cont<T> container_;
};

}
